package study.thread.threadpool;

import java.util.LinkedList;
import org.apache.log4j.Logger;

import com.sun.istack.internal.Pool;

import study.thread.basic.MyRun;

/*
 * 演示线程池的工作原理
 */
public class ThreadPool {

	private static final Logger Log = Logger.getLogger(ThreadPool.class);
	//指挥工作线程干活的调度线程组
	private ThreadWorker[] worker;
	//线程队列
	private LinkedList<Runnable> queue;
	//线程池的大小
	private int poolSize;

	public int getPoolSize() {
		return poolSize;
	}

	//initialize thread pool with pool size  
	public ThreadPool(int size) {

		poolSize = size;
		worker = new ThreadWorker[size];
		queue = new LinkedList<Runnable>();

		for (int i = 0; i < size; i++) {
			
			worker[i] = new ThreadWorker();
			
			//构造一个ThreadPool线程池对象后，其里面的调度线程就开始工作了
			worker[i].start();
		}

	}

	//add work queue  
	public void addQueue(Runnable runnable) {
		synchronized (queue) {
			queue.add(runnable);
			
			//wait和notify配对
			//Wakes up a single thread that is waiting on this object's monitor
			//唤醒其他的等待这个对象监视器的线程，同时释放对这个对象的监视器的所有权
			queue.notify();
		}
	}

	//worker do work  
	private class ThreadWorker extends Thread {

		public void run() {

			//runnable  
			Runnable runable;

			while (true) {

				synchronized (queue) {
					while (queue.isEmpty()) {
						try {
							//is work queue is empty, wait  
							//wait和notify配对
							queue.wait();
						} catch (Exception e) {
							Log.error("pool queue wait", e);
						}
					}

					//get work in queue, and remove it   
					runable = queue.removeFirst();
				}

				try {
					//do work  
					runable.run();
					System.out.println("-->"+this.getName()+"-->");
				} catch (RuntimeException e) {
					e.printStackTrace();
					Log.error("unknow runtime exception", e);
				}

			}
		}

	}
	//内部类  
	class SSS implements Runnable {
		private String abc;

		public void setAbc(String aaaaa) {
			this.abc = aaaaa;
		}

		public void run() {
			System.out.println("do runnable " + abc);
			System.out.println("--"+this.getClass().getName());
		}
	}
	
	public static void main(String[] args) {

		//构造一个线程池对象
		ThreadPool pool = new ThreadPool(10);



		for (int i = 0; i < 2; i++) {
			
			//用外部类的对象构建一个内部类
			SSS a = pool.new SSS();
			a.setAbc(String.valueOf(i + 1));
			
			//将工作线程类对象添加到线程池的队列里面
			pool.addQueue(a);
			
			MyRun myRun = new MyRun(i);
			
			pool.addQueue(myRun);
		}
		System.out.println("==========《主线程退出》==========");
	}

}
